<?php
include_once (_CORE_PATH . "module/module_related_base.php");
abstract class controller_prototype_class extends module_related_base_class
{
    /**
		общее имя модуля
     */
    protected $_selfName = '';
    /**
		id контроллера
     */
    protected $_selfId = 0;
    /**
		название контроллера
     */
    protected $_selfTitle = '';
    /**
		объект модели для контроллера
     */
    protected $_mod = null;
    /**
		коллекция контроллеров
     */
    protected $_ctrls;
    /**
		коллекция библиотек
     */
    protected $_libs;
    protected $_request;
    protected $_response;
    protected $_user;
    protected $_actionList = array();

    public function __construct (active_module_class $module, $ctrlName)
    {
        parent::__construct($module);
        
        MozgLang::Load('module_' .$module->GetName(). '_ctrl_' .$ctrlName);
        $this->SetSelf($ctrlName);
        
        $this->_ctrls = $this->GetModule()->GetCtrlCollection();
        
        $this->ControllerInit();
    }
    
    /**
		обёртка для вызова библиотек
	*/
    protected function Libs()
    {
    	if (!$this->_libs)	$this->_libs = $this->GetModule()->GetLibCollection(); 
    	return $this->_libs;   	
    } 

	protected function User()
	{
    	if (!$this->_user) $this->_user = $this->GetModule()->GetUser();
    	return $this->_user;		    
	}
    
	protected function Request()
	{
    	if (!$this->_request) $this->_request = $this->GetModule()->GetRequest();
    	return $this->_request;		    
	}	

	protected function Response()
	{
    	if (!$this->_response) $this->_response = $this->GetModule()->GetResponse();
    	return $this->_response;		    
	}		
	
	protected function GetTemplator()
	{
		return $this->GetModule()->GetTemplator();
	}
	
    /**
		Инициализация контроллера
     */
    protected function ControllerInit ()
    {}
    /**
		Инициализация Pr экшена
     */
    protected function PrimaryActionInit ($basicActionName)
    {}

    /**
		устанавливает свойства контроллера
     */
    final private function SetSelf ($modName)
    {
        $this->_selfName = $modName;
        
        $details = $this->GetModule()->GetCtrlDetails($modName);
      
        $this->_selfId = $details['id'];
        $this->_selfTitle = $details['title'];
        $this->_actionList = $this->GetModule()->GetCtrlActionList($modName);
        return $this;
    }
    /**
		возвращает имя контроллера
     */
    final public function GetSelfName ()
    {
        if (! $this->_selfName)
            throw new Exception('Имя контроллера не установлено');
        return $this->_selfName;
    }
    /**
		возвращает id контроллера
     */
    final public function GetSelfId ()
    {
        //if (!$this->_selfId) throw new Exception('Id контроллера не установлено');
        return $this->_selfId;
    }
    /**
		возвращает заголовок контроллера
     */
    final public function GetSelfTitle ()
    {
        return $this->_selfTitle;
    }

    /**
		возвращает id экшена по его имени в списке экшенов контроллера
     */
    protected function GetActionId ($basicActionName)
    {
        if (!isset($this->_actionList[$basicActionName])) return false; 
        return $this->_actionList[$basicActionName]['id'];
    }
    /**
		возвращает тип экшена по его имени.
		return
		1 - PrAction
		2 - ScAction
		0 - экшен не найден или неправильный
     */
    public function GetActionType ($actionName)
    {
        if (method_exists($this, $actionName)) return 0;
        elseif (method_exists($this, $actionName . 'Action'))
        {
	        switch (substr($actionName, -2))
	        {
	            case 'Pr':
	                return 1;
	            case 'Sc':
	                return 2;                          
	        }             
        }
        return 0;
    }
    
    /**
		сюда можно впихнуть дополнительную проверку,
		после того как юзер прошёл основную проверку
	*/
    public function CheckAccessWithUserGranted()
    {
		return true;    	
    }
    
    public function CheckAccess ($basicActionName)
    {
        if ($this->User()->CheckAccess($this->GetModule()->GetName(), $this->GetSelfName(), $basicActionName))
        {
        	return $this->GetModule()->CheckAccessWithUserGranted($this, $basicActionName);
        }
        	
        return false;
    }
    /**
     	Пример:
		$actionName = 'methodPr'
		или
		$actionName = 'methodSc'
	*/
    protected function __call ($actionName, $args)
    {
        $actionType = $this->GetActionType($actionName);
        if (! $actionType)
            throw new Exception('Метод ' . $actionName . ' контроллера ' . $this->GetSelfName() . ' не найден');           

        $basicActionName = substr($actionName, 0, -2);    
            
            // проверяем доступ
        if (! $this->CheckAccess($basicActionName))
        {
            $postFix = 1 == $actionType ? 'Pr' : 'Sc';
            
            if (! $this->User()->IsLogged()) return $this->_ctrls->errors->{'NotLogged' .$postFix}();
	        else return $this->_ctrls->errors->{'NotAccess' .$postFix}();   	            
        }

        $prepareStatus = true;
        if (1 == $actionType) $prepareStatus = $this->PrimaryActionInit($basicActionName);
        
        if ($prepareStatus === false) return;
        
        return call_user_func_array(array($this, $actionName . 'Action'), $args);
    }
    
    public function ActionExists($actionName)
    {
    	return method_exists($this, $actionName. 'Action');
    }
    
    public function PrAction()
    {
    	
    }
    
    public function defaultPrAction()
    {
    	return $this->Pr();
    }    
}